package client;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JPanel;

public class Main extends JPanel implements MouseMotionListener {

	private static final long serialVersionUID = 2244045894979126503L;
	private final int PADDLE_WIDTH = 10;
	private final int PADDLE_HEIGHT = 60;
	private final int PADDLE_X_OFFSET = 10;
	private Paddle[] paddles = new Paddle[2];
	private int radius = 7;
	private Ball ball;
	public int[] score = {0,0};
	/**
	 * This is used because if a number is randomly generated for ai collision every update,
	 * then the ai paddle continuously jerks around.
	 */
	private int spotToHit;


	public Main() {
		JFrame main = new JFrame();
		main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		addMouseMotionListener(this);
		main.setTitle("Pong Multi");
		main.setSize(500,500);
		main.setLocation(100, 100);
		setSize(500,500);
		main.setResizable(false);
		main.setVisible(true);
		main.add(this);
		ball = new Ball(getWidth()/2-radius, getHeight()/2-radius, radius);
		paddles[0] = new Paddle(1, PADDLE_X_OFFSET + PADDLE_WIDTH, getHeight()/2-PADDLE_HEIGHT/2, PADDLE_WIDTH, PADDLE_HEIGHT);
		paddles[1] = new Paddle(2, getWidth()- PADDLE_X_OFFSET - PADDLE_WIDTH, getHeight()/2-PADDLE_HEIGHT/2, PADDLE_WIDTH, PADDLE_HEIGHT);
		spotToHit = (int) (Math.random() * paddles[1].height);
		Run r = new Run(this);
		r.setRunning(true);
		r.start();
	}

	@Override
	public void paint(Graphics g) {
		g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.GREEN);
		for (Paddle p : paddles) {
			if(p != null) {
				p.drawOntoGraphics(g);
			}
		}
		if (ball != null)
			ball.drawOntoGraphics(g);
	}

	public static void main(String[] args) {
		new Main();
	}

	@Override
	public void mouseDragged(MouseEvent e) {}

	@Override
	public void mouseMoved(MouseEvent e) {
		if (e.getY() + PADDLE_HEIGHT/2 <= getHeight() && e.getY() - PADDLE_HEIGHT/2 >= 0) {
			paddles[0].y = e.getY() - PADDLE_HEIGHT/2;
		}
	}

	private void checkBallCollisions() {
		if (ball.getX() + ball.getDiameter() <= 0 || ball.getX() >= getWidth()) {
			ball = new Ball(getWidth()/2 - radius, getHeight()/2 - radius, radius);
		}
		if (ball.getY() <= 0 || ball.getY() + ball.getDiameter() >= getHeight()) {
			ball.inverseYSpeed();
		}
		for(Paddle p : paddles) {
			if(ball.getBall().intersects(p)) {
				if(ball.getBall().getBounds2D().intersectsLine(p.getCollisionSide())) {
					ball.setYSpeed(newYDir(p));
					ball.incrementXSpeed();
					ball.inverseXSpeed();
					return;
				} else {
					ball.inverseYSpeed();
					if(ball.getY() > p.getY() + p.getHeight()) {
						ball.getBall().getBounds().y = (int) (p.getY() + p.getHeight());
					} else if(ball.getY() + ball.getDiameter() < p.getY()) {
						ball.getBall().getBounds().y = (int) (p.getY());
					}
					return;
				}
			}
		}
	}

	private void moveAIPaddle() {
		if(ball.getY() > paddles[1].y+spotToHit) {
			paddles[1].y += Math.abs(ball.getYSpeed());
		} else {
			paddles[1].y -= Math.abs(ball.getYSpeed());
		}
	}

	private int newYDir(Paddle p) {
		int middleY = p.y+PADDLE_HEIGHT/2;
		int middleBall = ball.getY() + ball.getRadius();
		int dir = ball.getYSpeed();
		if (middleBall < middleY) {	//ball is above middle line	
			dir = (int) -(Math.sqrt((middleY-middleBall)*(middleY-middleBall))/5);		
		} else if (middleBall > middleY) {		
			dir = (int) (Math.sqrt((middleBall-middleY)*(middleBall-middleY))/5);		
		}
		if(dir > 5) dir = 5;
		else if(dir < -5) dir = -5;
		if(dir == 0 && middleBall != middleY) {
			if(middleBall > middleY) {
				dir = 1;
			} else {
				dir = -1;
			}
		}
		return dir;
	}

	public void gameUpdate() {
		ball.move();
		checkBallCollisions();
		moveAIPaddle();
	}

}